#include "CMyMDApi.h"
#include "CMyMDSpi.h"
#include <string.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <unistd.h>
#include <chrono>

using namespace std;

//定义行情接口读取config实例
rr::RrConfig mdconfig;

CMyMDApi::CMyMDApi()
{
	//以下为不读取配置文件时的默认参数

	m_pszFrontAddr = const_cast<char*>("tcp://192.168.100.66:51205");
	m_pszBrokerId = const_cast<char*>("0001");
	m_pszUserId = const_cast<char*>("19920324");
	m_pszPasswd = const_cast<char*>("test@123");


	//配置文件路径设置与读取
	CfgFilePath = "config.ini";
	mdconfig.ReadConfig(CfgFilePath);

	//从配置文件读取交易前置地址
	tmp_pszFrontAddr = mdconfig.ReadString("network", "mdfrontaddr", "");
	m_pszFrontAddr = const_cast<char*>(tmp_pszFrontAddr.data());

	//从配置文件读取brokerid经纪公司编号
	tmp_pszBrokerId = mdconfig.ReadString("baseinfo", "brokerid", "");
	m_pszBrokerId = const_cast<char*>(tmp_pszBrokerId.data());

	//从配置文件读取登录账户
	tmp_pszUserId = mdconfig.ReadString("baseinfo", "userid", "");
	m_pszUserId = const_cast<char*>(tmp_pszUserId.data());

	//从配置文件读取登录密码
	tmp_pszPasswd = mdconfig.ReadString("baseinfo", "password", "");
	m_pszPasswd = const_cast<char*>(tmp_pszPasswd.data());


	m_iRequestId = 0;
}


CMyMDApi::~CMyMDApi()
{
}

//自定义接口初始化函数，绑定Spi类，输入前置地址，定义接受数据类型
void CMyMDApi::Init()
{
	m_pApi = CThostFtdcMdApi::CreateFtdcMdApi("");
	m_pSpi = new CMyMDSpi(this);

	m_pApi->RegisterSpi(m_pSpi);
	m_pApi->RegisterFront(m_pszFrontAddr);


	//赋值请求开始时间
	gettimeofday(&starttime, NULL);
	m_pApi->Init();//该行为CThostFtdcTraderApi类对象的初始化，并非CMyMDApi的初始化，我们定义的是CMyMDApi的初始化

	//进程主动控制
	serverrt = false;
	unique_lock<mutex> lk(mu);
	cond.wait_for(lk, chrono::seconds(5));
	if(serverrt)
	{
		cout << "lock end for init" << endl;
	}
	else
	{
		cout << "connect time out!!!" << endl;
		cout << "connect time out!!!" << endl;
		cout << "connect time out!!!" << endl;
	}

}

void CMyMDApi::Destroy()
{
	cout << "spi set null" << endl;
	m_pApi->RegisterSpi(NULL);
	cout << "to release" << endl;
	m_pApi->Release();
	cout << "set api null" << endl;
	m_pApi = NULL;
}


//自定义登陆函数
void CMyMDApi::RequestLogin()
{
	CThostFtdcReqUserLoginField reqlogin;

	strcpy(reqlogin.BrokerID, m_pszBrokerId);
	strcpy(reqlogin.UserID, m_pszUserId);
	strcpy(reqlogin.Password, m_pszPasswd);

	//赋值请求开始时间
	gettimeofday(&starttime, NULL);
	//调用认证函数
	int iRet = m_pApi->ReqUserLogin(&reqlogin, m_iRequestId++);

	//进程主动控制
	serverrt = false;
	unique_lock<mutex> lk(mu);
	cond.wait_for(lk, chrono::seconds(5));
	if(serverrt)
	{
		cout << "lock end for login" << endl;
	}
	else
	{
		cout << "connect time out!!!" << endl;
		cout << "connect time out!!!" << endl;
		cout << "connect time out!!!" << endl;
	}
}

void CMyMDApi::SubMD(char *instrumentlist[], int instrcount)
{
	//通过传入的合约指针数组以及合约数量进行订阅
	m_pApi->SubscribeMarketData(instrumentlist, instrcount);

	//主动线程控制
	serverrt = false;
	unique_lock<mutex> lk(mu);
	//不设置退出时间
	cond.wait(lk);
	if(serverrt)
	{
		cout << "lock end for login" << endl;
	}
	else
	{
		cout << "connect time out!!!" << endl;
		cout << "connect time out!!!" << endl;
		cout << "connect time out!!!" << endl;
	}

}


//配置文件读取函数定义内容
static bool readConfigFile(const char * cfgfilepath, const string & key, string & value)
{
	fstream cfgFile;
	cfgFile.open(cfgfilepath);//打开文件	
	if (!cfgFile.is_open())
	{
		cout << "can not open cfg file!" << endl;
		return false;
	}
	char tmp[1000];
	while (!cfgFile.eof())//循环读取每一行
	{
		cfgFile.getline(tmp, 1000);//每行读取前1000个字符，1000个应该足够了
		string line(tmp);
		size_t pos = line.find('=');//找到每行的“=”号位置，之前是key之后是value
		if (pos == string::npos) return false;
		string tmpKey = line.substr(0, pos);//取=号之前
		if (key == tmpKey)
		{
			value = line.substr(pos + 1);//取=号之后
			return true;
		}
	}
	return false;
}